/*
 *  Class name: PlayerServiceBean.java
 *  Version: 1.0
 *  Date: 30.10.2013
 */
package cz.muni.fi.pa165.soccergamesarchive.businesslayer.services;

import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.PlayerDTO;
import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.PlayerDetailDTO;
import cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.daos.PlayerDAO;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.entities.Player;
import cz.muni.fi.pa165.soccergamesarchive.validators.ValidatorTest;
import java.util.List;
import java.util.Map;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import static cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler.createErrorMessage;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transform;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transformList;
import static cz.muni.fi.pa165.soccergamesarchive.validators.PlayerValidator.validatePlayer;

/**
 * Service bean to manage player entity
 *
 * @author Michal Ďuriš
 */
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@DeclareRoles("Archiver")
@Stateless
public class PlayerServiceBean implements PlayerServiceBeanLocal {

    @EJB
    private PlayerDAO playerEntityManager;

    public PlayerServiceBean() {
    }

    public void setPlayerEntityManager(PlayerDAO playerEntityManager) {
        this.playerEntityManager = playerEntityManager;
    }

    @RolesAllowed("Archiver")
    @Override
    public PlayerDTO addPlayer(PlayerDTO player) throws RuntimeException {

        Player playerEntity = transform(player,
                Player.class);

        validatePlayer(playerEntity, ValidatorTest.NULL_TEST,
                ValidatorTest.CORRECT_RECORD_TEST);

        return transform(playerEntityManager.addPlayer(
                playerEntity), PlayerDTO.class);
    }

    @RolesAllowed("Archiver")
    @Override
    public PlayerDTO changePlayer(PlayerDTO player) throws RuntimeException {

        Player playerEntity = transform(player,
                Player.class);

        validatePlayer(playerEntity, ValidatorTest.FULL_TEST);

        return transform(playerEntityManager.changePlayer(
                playerEntity), PlayerDTO.class);
    }

    @RolesAllowed("Archiver")
    @Override
    public void removePlayer(PlayerDTO player) throws RuntimeException {

        Player playerEntity = transform(player,
                Player.class);

        validatePlayer(playerEntity, ValidatorTest.NULL_TEST,
                ValidatorTest.ID_TEST);

        playerEntityManager.removePlayer(playerEntity);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<PlayerDTO> getAllPlayers() throws RuntimeException {

        return transformList(
                playerEntityManager.getAllPlayers(), PlayerDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<PlayerDTO> getLimitedNumberOfPlayers(int offset, int limit,
                                                     Map<String, Object> filterMap,
                                                     Map<String, Boolean> orderMap)
            throws RuntimeException {

        if (offset < 0 || limit <= 0) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transformList(
                playerEntityManager.getLimitedNumberOfPlayers(offset, limit,
                        filterMap, orderMap),
                PlayerDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public PlayerDTO getPlayerById(Long id) throws RuntimeException {

        if (id == null || id < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transform(playerEntityManager.getPlayerById(
                id), PlayerDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public PlayerDetailDTO getPlayerDetail(Long id) throws RuntimeException {

        if (id == null || id < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return playerEntityManager.getPlayerDetail(id);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public int getFilteredPlayersCount(Map<String, Object> filterMap) throws
            RuntimeException {

        return playerEntityManager.getFilteredPlayersCount(filterMap);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<PlayerDTO> findPlayer(String firstName, String lastName) throws
            RuntimeException {

        if ((firstName == null || firstName.equals(""))
                && (lastName == null || lastName.equals(""))) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transformList(
                playerEntityManager.findPlayer(firstName, lastName),
                PlayerDTO.class);
    }

}
